home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Arsenal Files 6
/
The Arsenal Files 6 (Arsenal Computer).ISO
/
prg_casm
/
jlvesa11.zip
/
JLVESA22.ASM
< prev
next >
Wrap
Assembly Source File
|
1995-11-14
|
8KB
|
366 lines
; This routine is part of VESA SVGA -library
;
; Copyright 1994 Johannes Lehtinen
; All rights reserved
model large,c
p386
include "jlvesads.asm"
extrn vesa_repos_w:far
segment jlvesa22_TEXT USE16 'CODE'
assume cs:jlvesa22_TEXT
; void JVImage_DrawOnLimited(JLSWord x, JLSWord y, JLUWord width,
; JLUWord height, void *image, JLSWord lx,
; JLSWord ly, JLUWord lwidth, JLUWord lheight)
;
; Puts image to screen, color 0 is transparent. Output only in limited area.
; Some information
bl_linesleft dw ? ; Lines left to draw
bl_repolines dw ? ; Lines before next reposition
bl_overflines dw ? ; Lines before next overflow
bl_left dw ? ; Pixels outside the left border
bl_up dw ? ; Pixels outside the upper border
bl_right dw ? ; Pixels outside the right border
bl_width dw ? ; Pixels on screen horizontally
proc JVImage_DrawOnLimited far
public JVImage_DrawOnLimited
push bp
mov bp,sp
push si
push di
push ds
push es
push fs
mov ax,JLVesa_Data
mov fs,ax
mov [cs:bl_left],0
mov [cs:bl_up],0
mov [cs:bl_right],0
; Make sure the block is on limited area
; Check that x>=lx
mov ax,[ss:bp+18]
cmp [ss:bp+6],ax
jge short x_not_below
; X is less than lx
sub ax,[ss:bp+6]
mov [cs:bl_left],ax
; Check that y>=ly
x_not_below:
mov ax,[ss:bp+20]
cmp [word ptr ss:bp+8],ax
jge short y_not_below
; Y is less than 0
sub ax,[ss:bp+8]
mov [cs:bl_up],ax
; Calculate pixels on limited area at this point
y_not_below:
mov ax,[ss:bp+10]
sub ax,[cs:bl_left]
mov [cs:bl_width],ax
mov ax,[ss:bp+12]
sub ax,[cs:bl_up]
mov [cs:bl_linesleft],ax
mov ax,[ss:bp+6]
add ax,[ss:bp+10]
sub ax,[ss:bp+18]
cmp [ss:bp+22],ax
jg short width_not_above
; Wider than limited area
sub ax,[ss:bp+22]
mov [cs:bl_right],ax
mov ax,[ss:bp+10]
sub ax,[cs:bl_left]
sub ax,[cs:bl_right]
mov [cs:bl_width],ax
width_not_above:
mov ax,[ss:bp+8]
add ax,[ss:bp+12]
sub ax,[ss:bp+20]
cmp [ss:bp+24],ax
jg short height_not_above
; Heigher than limited area
sub ax,[ss:bp+24]
mov bx,ax
mov ax,[ss:bp+12]
sub ax,[cs:bl_up]
sub ax,bx
mov [cs:bl_linesleft],ax
; Check that width or height is not negative
height_not_above:
cmp [cs:bl_width],0
jle end_of_block
cmp [cs:bl_linesleft],0
jle end_of_block
; Calculate absolute address of starting point
xor eax,eax ; Calculate address of start of line
xor ebx,ebx
mov ax,[ss:bp+8]
add ax,[cs:bl_up]
mov bx,[fs:LWidth]
mul ebx
mov bx,[ss:bp+6] ; Calculate address of starting point
add bx,[cs:bl_left]
add eax,ebx
add eax,[fs:AStart] ; Calculate address if scrolled
mov edx,eax
; Initialize registers used
mov ax,[fs:WWSeg]
mov es,ax
cld ; Direction forward
; Reposition window if necessary
cmp [fs:WAStart],edx
jbe short not_bef_win
call far vesa_repos_w
jmp short go_drawing
not_bef_win:
mov eax,[fs:WAStart]
add eax,[fs:WSize]
cmp edx,eax
jb short go_drawing
call far vesa_repos_w
; Calculate current offset
go_drawing:
mov edi,edx
sub edi,[fs:WAStart]
; Read DS:SI
xor eax,eax
mov ax,[cs:bl_up]
xor ebx,ebx
mov bx,[ss:bp+10] ; EBX is width of image
push edx
mul ebx
pop edx
mov bx,[cs:bl_left]
add eax,ebx ; EAX is number of bytes to add to SI
xor esi,esi
mov si,[ss:bp+14] ; Read SI and make addition
add esi,eax
mov ebx,esi
shr ebx,4
and si,0fH
mov ax,[ss:bp+16] ; Read DS and make addition
add ax,bx
mov ds,ax
; Drawing loop
; First calculate, how many lines can be drawn without address overflow.
; Check both ES:DI and DS:SI.
; First check how many lines before window reposition
draw_loop:
cmp [cs:bl_linesleft],0
je end_of_block
mov eax,[fs:WAStart]
add eax,[fs:WSize]
dec eax
sub eax,edx
xor ebx,ebx
mov bx,[fs:LWidth]
push edx
xor edx,edx
div ebx
pop edx
cmp [cs:bl_linesleft],ax ; Check if fewer lines left than possible to draw on the page
jae short jump_0
mov ax,[cs:bl_linesleft]
jump_0:
mov [cs:bl_repolines],ax
; Then check how many lines before DS:SI overflow
mov eax,10000H
sub eax,esi
push edx
xor edx,edx
xor ebx,ebx
mov bx,[fs:LWidth]
div ebx
pop edx
cmp [cs:bl_linesleft],ax ; Check if fewer lines left than possible to draw before overflow
jae short jump_1
mov ax,[cs:bl_linesleft]
jump_1:
mov [cs:bl_overflines],ax
; Start drawing as many lines as possible before
; First check if normal lines can be drawn next at all
draw_line:
cmp [cs:bl_overflines],0
je overf_check
cmp [cs:bl_repolines],0
je short special_line
mov cx,[cs:bl_width] ; Width of the block
call near movsbtr
add di,[fs:LWidth] ; Move to the start of next line
sub di,[cs:bl_width]
xor ecx,ecx
mov cx,[fs:LWidth]
add edx,ecx
add si,[cs:bl_right]
add si,[cs:bl_left]
dec [cs:bl_repolines]
dec [cs:bl_overflines]
dec [cs:bl_linesleft]
jmp short draw_line
; Draw line, which is between two pages
special_line:
mov ecx,[fs:WAStart] ; Calculate how line is divided
add ecx,[fs:WSize]
sub ecx,edx
cmp [cs:bl_width],cx
jbe short line_on_current ; Line on current page
; Line is divided on both pages
mov bx,[cs:bl_width] ; BX = length of the line on next page
sub bx,cx
call near movsbtr ; Draw line on current page
xor ecx,ecx
mov cx,[fs:LWidth]
add edx,ecx ; Switch on next page
call far vesa_repos_w
mov edi,edx ; Calculate new DI
xor ecx,ecx
mov cx,[fs:LWidth]
sub edi,ecx
xor ecx,ecx
mov cx,[cs:bl_width]
add edi,ecx
sub edi,[fs:WAStart]
sub di,bx
mov cx,bx ; Draw line on next page
call near movsbtr
add di,[fs:LWidth] ; Move on the next line
sub di,[cs:bl_width]
add si,[cs:bl_right]
add si,[cs:bl_left]
dec [cs:bl_linesleft]
jnz draw_loop
jmp short end_of_block
; Line is on current page
line_on_current:
mov cx,[cs:bl_width] ; Draw line on this page
call near movsbtr
xor ecx,ecx
mov cx,[fs:LWidth]
add edx,ecx
call far vesa_repos_w
mov edi,edx ; Move to start of next line
sub edi,[fs:WAStart]
add si,[cs:bl_right]
add si,[cs:bl_left]
dec [cs:bl_linesleft]
jnz draw_loop
jmp short end_of_block
; Handle DS:SI overflow
overf_check:
mov ax,si
shr ax,4
mov bx,ds
add ax,bx
mov ds,ax
and si,0fH
jmp draw_loop
; End drawing
end_of_block:
pop fs
pop es
pop ds
pop di
pop si
pop bp
retf
endp JVImage_DrawOnLimited
; This procedure MOVSBs CX bytes (color 0 transparent)
movsbtr_0:
inc di
inc si
dec cx
jz short movsbtr_end
movsbtr:
cmp [byte ptr ds:si],0
je short movsbtr_0
movsb
dec cx
jnz short movsbtr
movsbtr_end:
retn
ends
end